/**************************************************************************
*   Copyleft 2009 by        											  *
*	Iwanicki Krzysztof													  *
*   <www.gamma.mini.pw.edu.pl/~iwanickik>		                          *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
***************************************************************************/
#include "./vFrustum.h"

namespace Vendetta {
	vFrustum::vFrustum() {
	
	}

	vFrustum::vFrustum(const vFrustum& frustum) {
		mPlanes[VTOP] = frustum.mPlanes[VTOP];
		mPlanes[VBOTTOM] = frustum.mPlanes[VBOTTOM];
		mPlanes[VLEFT] = frustum.mPlanes[VLEFT];
		mPlanes[VRIGHT] = frustum.mPlanes[VRIGHT];
		mPlanes[VNEAR] = frustum.mPlanes[VNEAR];
		mPlanes[VFAR] = frustum.mPlanes[VFAR];
	}

	vFrustum::~vFrustum() {
	
	}

	vFrustum& vFrustum::operator=(const vFrustum& frustum) {
		if (this != &frustum) {
			mPlanes[VTOP] = frustum.mPlanes[VTOP];
			mPlanes[VBOTTOM] = frustum.mPlanes[VBOTTOM];
			mPlanes[VLEFT] = frustum.mPlanes[VLEFT];
			mPlanes[VRIGHT] = frustum.mPlanes[VRIGHT];
			mPlanes[VNEAR] = frustum.mPlanes[VNEAR];
			mPlanes[VFAR] = frustum.mPlanes[VFAR];
		}

		return *this;
	}

	vBool vFrustum::IsInFrustum(const vAxisAlignedBoundingBox& aabb) {
		for(vUInt uiInd = 0; uiInd < 6; uiInd++) {
			if (mPlanes[uiInd].Distance(aabb.VertexFromPositiveNormal(mPlanes[uiInd].Normal())) < 0) {
				return false;	// Outside
			} else if (mPlanes[uiInd].Distance(aabb.VertexFromNegativeNormal(mPlanes[uiInd].Normal())) < 0) {
				return false;	// Intersection
			}
		}

		return true;
	}

	vBool vFrustum::IsInFrustum(const vSphere& sphere) {
		vReal distance;

		for(vUInt uiInd = 0; uiInd < 6; uiInd++) {
			distance = mPlanes[uiInd].Distance(sphere.Center());

			if (distance < -sphere.Radius()) {
				return false; // Outside
			} else if (distance < sphere.Radius()) {
				return false; //Intersection
			} 
		}

		return true;
	}

	vBool vFrustum::IsInFrustum(const vPoint3D& point) {
		for(vUInt uiInd = 0; uiInd < 6; uiInd++) {
			if (mPlanes[uiInd].Distance(point) < 0) {
				return false;	//Outside
			}
		}

		return true;
	}

}